Repository navigation
Native open/save file dialogs with platform hints, options and preview - #6052
Conversation
… previews Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…review Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…download Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d options Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open uses initForOpeningContentTypes (filter UTTypes, extensions, folder), multi-select, directoryURL and shouldShowFileExtensions; picked items are copied to tmp. Save stages content in the caches dir off the EDT and exports it with initForExportingURLs asCopy. Results return through a per-request id and are delivered on the EDT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…filters, options and hints Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Filters become an accessory popup that switches the allowed types, options render as checkbox/popup/text controls in the same accessory stack, and the MAC_* hints map to the panel properties. Answers use NativeFileDialogCodec; saves are written through completeSaveDialog. No accessory Component or preview on the Mac yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Compared 12 screenshots: 12 matched. |
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
Cloudflare Preview
|
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Compared 214 screenshots: 214 matched. |
|
Compared 178 screenshots: 178 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 71c2a5a6ee
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Compared 193 screenshots: 193 matched. Benchmark ResultsDetailed Performance Metrics
|
- Copyright headers on the new tests; classify the fallback save form in FrameworkChromeNeverWindowsTest; Vale quote punctuation in the guide. - Linux: add the filter's extension in the GTK native and confirm the overwrite of that name, since GTK only checked the typed basename. - Core: saving a sourceFile onto itself no longer truncates it. - Android: refuse to launch while another activity result is outstanding; stop reporting INITIAL_DIRECTORY, which only the URI hint honours. - iOS: convert extension filters to legacy UTIs before iOS 14; copy picked documents off the main thread. - JavaScript: report a dismissed picker as cancelled; a save too large for the heap still answers the callback. - Linux/Windows: deliver results on the EDT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6b20e3220
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Compared 193 screenshots: 193 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: Intel64 Family 6 Model 207 Stepping 2, GenuineIntel (baseline 1 performance regression:
Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
A change that moves performance ON PURPOSE records the new baseline in Result: performance regression |
- Core: a content writer still runs when the destination is the source file; the default implementation no longer advertises INITIAL_DIRECTORY. - JavaSE: filtered saves (and filtered opens on Windows, where AWT's FilenameFilter does nothing) use the Swing chooser, which confirms the overwrite of the name with the extension added. - Android: picks are checked against extension filters the MIME query could not express; a picked folder is copied to the cache so the result is a path FileSystemStorage can use. - macOS: filters given as UTIs reach allowedFileTypes. - iOS: close the staged export stream in a finally (SpotBugs DLS). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7879337058
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Windows: an IFileDialogEvents sink keeps the save dialog's default extension on the selected filter, so switching type no longer yields report.pdf.png. - Core: the fallback save form runs on the EDT when called from another thread, and the open fallback delivers on the EDT. - JavaSE: drop a preview render that finishes after the selection moved; parse file:/ and drive-letter URLs for the starting folder; saves that must not confirm an overwrite use the Swing chooser. - iOS: watchOS and tvOS use the Codename One fallback; a picker requested while another controller is presented answers cancelled instead of hanging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31852b9dda
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cfb4b397b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ard and coordinated copy, unchecked writer failures Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 90ee77db25
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… failure, wildcard fallback accept Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f37784b340
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…e accept union Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
…parators Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Compared 179 screenshots: 179 matched. Benchmark Results
Detailed Performance Metrics
ParparVM vs HotSpot (JDK 25): macOS arm64Runner CPU: Apple M1 (Virtual) (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Compared 176 screenshots: 176 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
Flutter vs Codename OneSame application, built both ways: Flutter's AOT compile of the gallery, and the identical Dart source transpiled to Java on Codename One. Lower is better for every metric, so a ratio above 1.00x means Codename One is ahead by that factor. android9 interleaved rounds; host load 0.51, 1.68, 1.46
Compute -- the VM workloads (
Gate: within tolerance against
ios9 interleaved rounds; host load 37.1, 31.5, 18.11
Compute -- the VM workloads ( Not measured: iOS compute is not measured: a device build needs signed hardware, and on the simulator Flutter runs its JIT debug engine rather than AOT code. The macOS row runs the same ParparVM and Dart AOT compilers on the same Apple silicon. Gate: within tolerance against
javascript9 interleaved rounds; host load 2.04, 1.33, 0.59
Compute -- the VM workloads (
Gate: within tolerance against
linux9 interleaved rounds; host load 0.26, 2.89, 2.38
Compute -- the VM workloads (
Gate: OUTSIDE THE BASELINE against
macos9 interleaved rounds; host load 2.85, 12.32, 11.81
Compute -- the VM workloads (
Gate: within tolerance against
windows9 interleaved rounds
Compute -- the VM workloads (
Gate: within tolerance against
Codename One wins 26 of 26 measured metrics across 6 platform(s). |
|
Compared 236 screenshots: 236 matched. |
|
Compared 171 screenshots: 171 matched. |
… fallback open dialog picks several files FileDialogHints held nothing but the key names for FileDialogRequest.hint(), so the constants now live beside the method that takes them. The Codename One open dialog, used by ports without a native one, answered a multi-select request with a single file. It now shows a file tree whose files toggle a check mark and returns every checked file in the order it was checked, and the fallback reports FileDialogFeatures.MULTI_SELECT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Command.equals compares names, so the cancel and accept buttons must be told apart by identity; master's #6052 tripped the forbidden-PMD gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR CI's forbidden PMD list fails on master's FileDialogSupport (#6052): the fallback dialog compares the picked Command by identity, which is right, since Command.equals compares names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…odename One apps (#5980) * Desktop compatibility runtimes: Swing, SwingX, JavaFX and FXML over Codename One swing-compat (java.awt, javax.swing, java.beans, javax.imageio and a SwingX subset) is authored already relocated under com.codename1.desktopcompat; javafx-compat is authored under the javafx names and relocated at build time. desktop-compat-runtime holds what both layers share, including shims for the host-backed JDK APIs a device lacks (java.io.File, java.net.URL, java.nio.file, ResourceBundle, java.util.logging, java.util.prefs). fxml-compiler turns FXML and JavaFX CSS into code and tables at build time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Build: one relocation pass for the Android, Swing and JavaFX layers ClassRelocator applies every active layer in one pass; CompatRewrites redirects the JDK members a device cannot have; the compliance check reports unsupported desktop API under its original name. remap-compat and import-desktop-project in Maven and Gradle, with the archetype wiring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Desktop compatibility: samples, integration tests, CI and documentation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Read .properties bundles as UTF-8 first; never report AutoCloseable as Closeable A stream bundle is UTF-8 when its bytes are well-formed UTF-8 and ISO-8859-1 otherwise, as the JDK has read them since Java 9. The compliance report no longer reverses a shim whose target is itself a JDK class. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix CI: drop tests of the abandoned design, keep master's Android desugaring, doc snippet roles The four core-unittests and AndroidDesugaringDependencyTest covered the core JDK host and the nio desugaring this PR no longer has. The nio desugar_jdk_libs variant clashed with the Flutter Android build (DartList.reversed), so AndroidGradleBuilder is master's again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Flutter: DateTime.parse on the framework's regex engine; rebaseline the JS gallery sizes dart.core.DateTime named java.util.regex, which no ParparVM target has and nothing relocates in an ordinary application: every native Flutter build failed on a missing java_util_regex_Pattern.h. It now uses com.codename1.util.regex, as RegExp already did. The PR's flutter-bench overlay justified the JavaAPI growth that moved to #6044; its linux rows are dropped and the javascript rows recalibrated from this PR's first gallery run on top of #6044 and #6055. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Flutter: DartList.reversed() clashes with Android's List.reversed() Android API 35 gives java.util.List a reversed() answering a List, and every Flutter plugin class extending DartList (dio's Interceptors) failed to compile in the generated Android project. Dart's reversed getter is now dartReversed() in Java; the transpiler emits that name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Extract the desktop runtime from its classes directory in a reactor build A reactor build that stops before packaging (mvn test over several modules, as the Java 8 CI leg runs) resolves the runtime to its target/classes directory, and the remap found no runtime jar. The directory is now read like the jar, leaving out com/codename1/impl the way the module's jar does. Also rebaselines the android and linux gallery sizes from their first run on top of #6044 and #6055. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Mark the fallback open dialog's identity comparison for PMD Command.equals compares names, so the cancel and accept buttons must be told apart by identity; master's #6052 tripped the forbidden-PMD gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ParparVM GC: never name a thread that may have exited A collection that cannot stop a thread records a root miss and skips the sweep, then names each missed thread with pthread_getname_np. The thread it could not stop is usually one that is exiting: markDeadThread deregisters it and the pthread ends, so the recorded handle can name a thread that no longer exists, and glibc reads its freed descriptor. The bulk conformance run, whose pool checks start and retire many threads, crashed with SIGSEGV in this diagnostic right after the skip line (vm-tests, StringBuilderGrowthApp, exit 139). The name is now read only for a handle still registered in allThreads, under the critical section markDeadThread takes, and blocked threads are released before that lock is taken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: skeleton, double-entry multi-asset ledger and hash-chained audit log
Phase 1 of a security-showcase bank sample beside Savor and Wayline. The
ledger holds fiat and crypto alike, enforces zero-sum entries, non-negative
customer balances by conditional update, and idempotency keys; the audit log
is a SHA-256 chain appended in the transaction of the change it records.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: sign-in, second factor, passkeys, lockout and audited auth
Phase 2. An OAuth 2 authorization server (PKCE public client, five-minute
access tokens, rotating refresh tokens) and a JWT resource server for /api
with roles read from the account on every request. TOTP via http.mfa with
recovery codes, passkeys via http.webAuthn, rate limits on sign-in, codes,
registration and password changes, a temporary per-account lockout, explicit
security headers, and every sign-in, refusal, enrolment and password change
appended to the hash-chained audit log. Registration opens a USD checking
account; admin-only routes verify the audit chain and the books.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: accounts, transfers, payees, cards, signed step-up and device policy
BankingApi over the ledger: own-account transfers, payments to payees with a
cooling-off period, withdrawals, simulated deposits and card spends, per-
transfer and daily limits, idempotency keys with a retry-as-lookup on a
concurrent duplicate, ES256 request signing by a registered device key
(clock skew and nonce replay refused), and an attested/rooted device policy
behind a simulated integrity verifier. Every change is audited in its own
transaction. MoneyTest 12 cases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: crypto exchange on the ledger, crypto withdrawals and limits, fresh sign-in for devices
Matching engine with price-time priority behind a market row lock, holds in
HOLD accounts, one balanced two-asset journal entry per trade, taker fee and
once-per-order rounding in the bank's favour, self-trade prevention, market
orders that never leave a hold. Allow-listed withdrawal addresses with
cooling-off, crypto limits valued at the index price, auth_time in access
tokens and a fresh sign-in (plus password without TOTP) to register a device.
Dev-profile market maker and price feed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: app foundation -- guarded network, PKCE sign-in with second factor and passkeys, device key and request signing, app lock, Security Center
Re-adds the common module. Every request passes one NetworkGuard (no
cleartext but the loopback dev server, a host allow-list, bundled pins,
AppShield delegated to). The device key is P-256 in portable Java (the
framework generates no EC keys and the iOS port signs RSA only), sealed in
a SecureEnvelope under a SecureStorage key, and signs the canonical form
now shared with the server (api/SignedRequest). Biometric lock on start,
resume and idle; secure screens, tapjacking blocking and clipboard
clearing; a Security Center that reports each protection honestly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix BigInteger division, modInverse and BigDecimal rounding; add EC P-256 key generation
TDivision.divide normalized with a 64-bit leading-zero count applied to a
32-bit digit (and the overflow test in step D3 used the same), so division,
mod and modInverse answered wrong values for ordinary 256-bit inputs. The
Montgomery/Hars inverses are replaced by extended Euclid. bitCount and
bitLength(int) had the same int-vs-long bug; BigDecimal.round always rounded
away from zero and floor threw for negatives.
KeyGenerator.ecP256() generates P-256 pairs through a new
generateEcKeyPair port method (JavaSE, Android, iOS). The iOS port now loads
EC keys in sign/verify (X9.62 DER signatures, as java.security returns) and
generates them with SecKey; a PKCS#8 EC key without its public point is
completed in Java (EcKeys) before signing, since SecKey cannot import one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: every screen -- onboarding, dashboard, accounts, transfers, payees, cards, exchange, crypto withdrawals, settings, admin
Onboarding registers with the server's password rule checked as typed, signs
in keeping the server session for a passkey ceremony, enrols TOTP with a QR
code (own byte-mode level-M encoder, checked against segno for versions 1-10
and every mask) and recovery codes, offers biometric unlock as a choice and
registers the device key. Money screens sign with RequestSigner, reuse one
idempotency key per payment across retries, and turn a missing-signature
refusal into an offer to register the device. Amounts are formatted and
parsed with integer math only (money/Amounts). Bundle_en.properties lists
every key; BundleTest keeps it complete.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: device key on core ES256, assets from the server, passkeys in Settings, pickers by id
DeviceKey/RequestSigner use KeyGenerator.ecP256 and Signature SHA256withECDSA
(DER to JOSE in RequestSigner); the hand-rolled P256 is gone. GET /api/assets
serves Ledger.assets and replaces the client's copied table. GET/DELETE
/api/account/passkeys plus a Settings section that adds a passkey through a
fresh kept sign-in. Pickers carry ids and make repeated labels distinct.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: CI workflow, live and web e2e, user's and implementor's guides
Fixes found on PostgreSQL, MySQL and the compiled server: cancel reads the
order behind the market lock, the server refuses MySQL above READ COMMITTED,
and the exchange avoids JDK APIs the compiled class library lacks. The app's
idle timer binds to the shown form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: offer it as an Initializr template
Template.BASTION with its resources (synced from scripts/bastion), a preview
from the web e2e sign-in screen, the selector and summary entries, its README
section and brand colour, fixture and matrix checks, and check-template.sh run
by bastion.yml. Migrations (.sql) are now rewritten as text; --brand-tint and
--radius-small are set only where a template's theme declares them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: browser sign-in with PKCE and TOTP, passkeys in the JS port, amr claim for device registration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: biometric-bound app key, PIN vault fallback, five languages, coded refusals
- security/Keys: one app key seals the device key and the refresh token
(SealedStorage under SecureStorageTokenStore). Copies: SecureStorage's
prompting tier (Keychain access control / Keystore user auth), a Vault
opened by a 6-12 digit PIN (KdfProfile, peppered from the OS store,
5 wrong tries wipe), and a plain copy only while neither exists.
- Lock/LockForm: biometric, then PIN, then sign in again; a stored session
is read only after the unlock. Onboarding and Settings set both up.
- Security Center reports the app key, PIN, refresh token and lock honestly
per platform.
- Android port: the biometric SecureStorage key is user-auth bound on every
API level (was skipped on 33+) and invalidated by biometric enrolment; an
old unbound key is replaced and its entries reported revoked.
- Server refusals carry stable codes (api/Refusal, backend Refused); the app
maps them to error.<code> bundle keys. es/fr/de/he bundles, Lang.CODES
restored, language choice in Settings; BundleTest checks completeness.
- Initializr template re-synced; guides updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: guide screenshots, diagrams and reference tables; website page
The user's guide shows every main screen, photographed from the browser build
by run-web-e2e.sh --guide (development profile, demo accounts, device policy
off so a payee payment can be shown). The implementor's guide gains figures
for the architecture, sign-in with PKCE and a second factor or passkey, a
signed payment, a trade's ledger entry and the audit chain, and tables of
security features (with whether each needs a cloud build), settings,
endpoints and the threat model. /bastion/ page and a flagship card.
The screenshots showed two theme faults, fixed: custom label styles without a
background painted an opaque white box (the dashboard's hero total was
invisible), and the three quick-action buttons truncated their labels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: client review round - sign-out wipes keys, owner-bound device keys, idempotency key signed, locale amounts, fail-closed guard
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion sample: server and framework review round
Idempotency keys scoped per owner under a c: prefix (system keys unreachable),
device registration needs otp/mfa/hwk in amr or the password, TOTP enrolment
needs a fresh sign-in, simulated integrity verifier only on dev profiles,
atomic lockout counting, order holds not movable by customers, fiat limits in
USD across currencies, profile-row lock for every cap, single-statement ledger
verify, paged audit verify, MariaDB tx_isolation fallback, uniform payee answers.
Framework: SecureStorage.setStrictBiometricBinding opt-in (Android default is
master's again; existing keys never deleted), EcKeys public point via a fixed
256-step Montgomery ladder with complete projective formulas.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Sensitive clipboard API; Bastion reload keeps the session; password step-up for TOTP enrolment
- Core: ClipboardContent.setSensitive/setClearAfter. Display schedules the
clear (only if nothing was copied since) through the new
CodenameOneImplementation.clearClipboardContent. Android tags the clip
with EXTRA_IS_SENSITIVE (API 24+ extras, honoured on 33+) and clears only
its own clip; iOS republishes the pasteboard local only with an expiry
date (IOSNative.restrictClipboard). SensitiveClipboardTest.
- Bastion: a reload (or restart) landed on the sign-in form because the
start looked for the session under SealedStorage's account name while
SecureStorageTokenStore writes under its own prefix. Session now marks
saved sessions itself under its own key (Session.Marked);
StoredSessionTest. run-web-e2e reload step passes.
- Bastion: adding an authenticator app after a password-only sign-in
needs the password on start and confirm (TotpStartDto, TotpCodeDto
password); client prompts. "Copy codes" restored via sensitive clips.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion review round 2: step-up lockout, signed card/payee/device changes, USD-valued limits, clipboard ownership
- AndroidImplementation.java: restore master's CRLF line endings; only the clipboard hunks differ.
- SignInGuard.recheck: in-session password checks (TOTP enrolment, device registration, device
revoke) refuse a locked account first, count a wrong password, clear on success, and do not
count a missing one.
- Unfreezing a card and raising its limit need a signature from a trusted device; renaming and
removing a payee are signed; revoking a device (now POST /api/devices/{id}/revoke) needs a
device signature or the password. Client signs all of them; docs and API table updated.
- Payee cooling-off and the step-up threshold value fiat in USD per currency.
- Card spends re-read the card behind its row lock inside the money transaction.
- Default clearClipboardContent clears only while the clipboard still holds the copied text;
iOS resets its expiry flag on every copy; Protect's timer only forgets the digest.
- EcKeys uses modInverse (fixed on this branch); stale session marker dropped when the store is
empty; taker-seller fee test on one-cent fills.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion review round 3: signed and limited orders with a price collar, fresh step-up, signed card/address/passkey changes, PIN counter in the secure store, translated Security Center
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion review round 4: locking frozen-account read, transition-free lock, re-armed idle timer, Hebrew passkey term
- LedgerAccountRepository.frozenNow is a no-op UPDATE, so it reads the
latest committed row and locks it on SQLite, PostgreSQL and MySQL alike.
- Lock disposes an open dialog without its closing animation and the lock
screen shows with no transition, so the form beneath is never painted.
- Lock.tick re-arms its timer in finally.
- Comments: placeOnce is woven despite being private and self-called; the
collar never follows fills; counting both trade sides is deliberate.
- Docs: PIN counter lives in the OS secure store; the clipboard clears
after a minute or at the next start.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* CI: guide snippets by include, copyright headers, Play Integrity raises minSdk to 21
Bastion's guides moved their shell blocks into docs/demos snippets; the new
core tests got the standard header and the Harmony/Bouncy Castle big-number
sources are listed as third-party; android.playIntegrity now lifts minSdk to
21, which com.google.android.play:integrity declares and the manifest merger
enforced.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* iOS: publish a sensitive clip local only and expiring on the first write
restrictClipboard used to re-publish the pasteboard with LocalOnly and the
expiry after setClipboardContent had already written it normally, leaving a
window in which Universal Clipboard could sync the value. It now arms the
options and setClipboardContent's single setItems:options: carries them.
Native names are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: a passkey spares the password only when the user was verified
Devices.register and SecondFactor treated amr "hwk" alone as strong, so a
passkey assertion without user verification skipped the password. Both now
need mfa/otp, or hwk together with user; MoneyTest covers hwk alone. The
implementors guide's shell blocks move to the docs/demos snippet file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion app: step-up dialog field keeps its height; client matches the server rule
Dialog.show stretched the lone password field to ~105px, which the web e2e
does not recognise as a field (CI timed out on 'Confirm it is you'); it is
now enclosed in a BoxLayout. DeviceSetup and onboarding ask for the password
under the same rule the server applies (mfa/otp, or hwk with user) instead
of whether an app is on the account now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Initializr: resync the Bastion template with the sample
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion guide: US spelling for LanguageTool
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion web e2e: check what a field holds, and retype on a doubled keystroke
CI typed a six-digit code that arrived as seven digits and was refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: the bank's books - chart of accounts, statements, close, audit
Chart of accounts over the ledger (positive = credit), journal, general
ledger, T-accounts, trial balance, balance sheet and income statement in
USD; period close with immutable closed periods; reversals; reconciliation
breaks; an AUDITOR role whose reads are on the audit chain; per-entity
audit trails, a chain report naming the first broken link and CSV/JSON
evidence exports; maker-checker approval above a threshold; chart and
candle endpoints; weeks of demo history.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* FileDialogSupport: mark the intentional Command identity check for PMD
PR CI's forbidden PMD list fails on master's FileDialogSupport (#6052): the
fallback dialog compares the picked Command by identity, which is right,
since Command.equals compares names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion app: charts, a staff console, and one way back on every screen
Every screen now has a back arrow or the side menu, never both. Sign-in and
lock use a branded landing band that respects the safe area, and the app
icon is a vector shield. Charts (com.codename1.charts) are on the dashboard,
the account, the exchange and the drill-downs (transaction, statement). The
staff console replaces AdminForm: journal, general ledger and T-accounts,
statements, reconciliation, period close, maker-checker approvals, audit
chain, trail, access log and evidence export. It has a sidebar on a desktop
and a section picker on a phone, and the auditor gets it read-only. New
strings are in all five bundles. Guide screenshots, the Initializr preview
and the template are regenerated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: refined charts, honest volume, fitted phone tables, composed preview
The console's volume and entry counts leave out order holds and releases:
they move a customer's own money into escrow and back, and the market
maker's requotes buried every earlier day under today. The market maker no
longer posts a second million-dollar float when the demo history funded it.
The last two days of history trade densely, so hourly candles have real
ranges. Money axes read $8k, the greeting uses the first name, the console
loses its duplicate heading, phone tiles and the statement fit the width,
and the Initializr preview is composed from the phone and the console.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: close the red-team findings in the books
- Maker-checker fails closed: an unpriced request waits, and what the maker
posted without a checker in the last 24h counts towards the threshold.
Pricing is asked, not caught, since a caught refusal dooms the transaction.
- A self-approval's APPROVAL_REFUSED row now commits.
- The journal evidence export pages through every entry.
- General ledger and T-account total in SQL and flag truncated listings.
- CSV guard covers leading tab and CR; periods() is a recorded staff read.
- Console: entries a day counts distinct entries; toasts follow the status;
the phone statement fits its opening and closing rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion guide: name the chart styles rather than a wildcard
check-guide-api-names read `BnChart*` as a misspelled class name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion guides: three LanguageTool findings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: serialize a maker's approvals, explain a refused e2e code
Approvals.adjust/reverse hold the maker's profile row (a no-op UPDATE,
as ProfileRepository.hold) before the idempotency lookup and the 24h
un-checked SUM, so concurrent just-under-threshold requests cannot all
post without a checker; a maker with no profile fails closed and waits.
BooksTest races eight such requests.
web-e2e.mjs: the authenticator key is re-read until it is 32 valid
base32 characters, and a refused code logs the test step, a secret
length/hash fingerprint, the server's Date skew and the last requests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Android clipboard: clear a timed clip by in-process ownership, not read-back
The description reads null for a background app on Android 10+, so the
timed clear almost never fired. Ownership is now a per-copy token, dropped
by the clip-changed listener and re-checked on resume. Bastion: sign-safe
opening balance, and a test seam that holds the per-maker race window open
so the lock's absence fails on PostgreSQL. BigDecimal.round documents HALF_UP.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Android clipboard: defer a background clear until the clip is provably ours
A timed clear that fires while the description is unreadable (background,
API 29+) no longer clears blind; it waits for resume and runs only if the
token still matches. Resume resets the clip-change count a background
clear could leave unconsumed. Bastion's approvals test seam is now
package-private, reached through a test-only hook.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Android clipboard: retry a deferred clear on window focus, document process death
Android 10+ reads the clipboard only with window focus, which arrives after
onResume; retry the pending clear from onWindowFocusChanged(true). Document
that the deferred clear does not survive process death and how Bastion covers
it. Restore getNativeThemeSettings' original line endings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: keep the clipboard record until a read decides it, key its digest
The leftover check now runs after a form shows, on resume and after the
clear falls due, keeps the record while the read answers null, and skips
iOS. The digest is HMAC-SHA256 under a key in secure storage. Android:
give the focus and resume clip checks their own doc comments.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion web e2e: let a typed field settle before reading it back
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Flutter bench: accept the Android code-size move from the clipboard handling
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Initializr: generate Bastion's probes at its own release, test the refusal below it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: button spacing, a real card, full receipts and statements, no cut-off values
- Buttons: smaller consistent label (2.5mm) with side padding; Ui.across puts
the theme's gap (bnButtonGapMm) between buttons and wraps a row that does
not fit (main action on its own row) instead of shrinking or cutting labels.
- Cards: CardFace draws an ID-1 card (1.586:1, rounded, gradient, chip, brand,
number in fours, holder, expiry, frozen overlay); details (status, type,
account, expiry, daily limit with a used-today meter) and recent card payments.
- Landing headings wrap; the authenticator key shows whole as monospaced
groups of four.
- Receipt: "Receipt" title with a close button; status, from, to, amount, fee,
balance after, time, note and the full Reference wrapping.
- Statement: header with account, period, opening/closing and totals; columns
for description, category, reference, in/out, amount and running balance,
a column chooser, more columns on wide windows, and every row opens in full.
- PostingDto carries the entry's kind and memo for descriptions and categories.
- l10n for en/es/de/fr/he; web e2e reads the grouped key and skips read-only
text areas; screenshots regenerated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: copy buttons, printable reports, and sign-in held to the strongest factor
- Ui.copyable / Ui.copyButton: selectable value plus a copy icon; secrets
(keys, account and card IDs, recovery codes) go through Protect.copy and
clear themselves. Used for references, ledger entries and postings,
account/card IDs, coin addresses, passkey and device key IDs, entry IDs,
audit head hash and evidence SHA-256.
- Printout: a report laid out as monospaced lines (header, tables, totals),
drawn on an image and printed through com.codename1.printing.Printer.
Print on the statement, receipt, transaction, journal entry, general
ledger, trial balance, balance sheet, income statement, audit chain,
audit trail, access log and evidence export; no button where printing is
unsupported. Table records its rows for printing.
- Sign-in offers passkey, then biometric unlock of the stored session, then
password and code. The server requires user verification on passkeys,
and SignInGuard refuses a password (and an authenticator code) for an
account with a passkey; password plus a recovery code is the recovery
path. AuthTest covers both; web-e2e checks the refusal end to end.
- Developer guide, five bundles and guide screenshots updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* JavaScript port: typing on a form with text selection on is no longer lost
A press queued 'finish editing' through a thread-spawning callSerially that
ran after the same click had opened the field, closing it again; and the
legacy editor committed on blur in a queued callback, after a button's action
had read the model. The press now finishes only the session it saw, and blur
commits the value at once. Regression check: review=selectionsignin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: print reports as a paginated PDF with repeated headers and page numbers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: errors and sentences wrap, text selection on every form
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion web e2e: one tap opens a market, no retry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Initializr: resync the Bastion template with the sample
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: Bastion guides, contractions for Vale
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Security: Keccak-256, SHA3-256 and secp256k1 ECDSA in core, shared with the backend
The two primitives an Ethereum wallet needs, in portable Java so the
Bastion sample can sign chain transactions on the device or on the server
with the same class.
Hash gains KECCAK256 (original 0x01 padding, what Ethereum hashes with)
and SHA3_256 (FIPS 202, 0x06), one Keccak-f[1600] sponge in
MessageDigestImpl behind both; Hmac learns the 136-byte rate as their
block size.
Secp256k1 is written from the math, not ported from libsecp256k1: a 16x16
bit limb field whose reduction is a few bounded fold-and-carry passes, the
Renes-Costello-Batina complete projective addition (no doubling or
infinity special case to branch on), and a 4-bit fixed-window ladder with a
constant-time table scan. Everything that touches a private key or nonce
is constant time; verify and recover reuse the same code. Signatures are
RFC 6979 deterministic, low-S, and carry the recovery id; verify rejects
high-S as libsecp256k1 does, recover accepts it as ecrecover does.
Private and public tweak addition and point addition cover BIP32.
Tests: Keccak and SHA3 known answers including the NIST million-a
multi-block vector, generator multiples, the published RFC 6979 secp256k1
vectors, the Ethereum address of a published test key, recover(sign(h)),
tampering, high-S handling and tweak agreement.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Bastion: real Ether on chain, security audit fixes, checklist, UI polish
- chain/: EIP-1559 signing, RLP, EIP-55, BIP-32/44 keys, JSON-RPC node
client; per-customer deposit addresses, confirmation-depth scanning that
stops on a reorg, sweeps, withdrawals under a lease and compare-and-set
states, fees posted at the receipt's cost, and a reserves breaker that
holds a withdrawal custody cannot back. Known-answer tests against
eth-account, and run-chain-test.sh drives a geth development node (CI job).
- Audit fixes: payee removal keeps its cooling-off, a device needs a second
factor, staff need one for the console, daily caps on new payees and
addresses, rate limits per principal, production refuses default secrets,
expired nonces purged, ETH addresses checked by EIP-55.
- Console custody panel, Receive crypto screen with an EIP-681 QR code.
- UI: chips instead of stretched badges, gaps between console buttons and
charts, a spinner with skeleton cards while loading; the web e2e waits
for content before each screenshot.
- Initializr e2e: a template is offered only from its release floor, and
the pinned versions must be releases, never snapshots.
- Implementor's guide: on a real chain, and a security checklist.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: compilable secp256k1 snippet, Bastion guide prose gates
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Bastion: adopt master's Instant mapping and PKI; App Attest; skill update
- Entities hold java.time.Instant timestamps (same BIGINT columns, no
migration); repository time parameters are Instant, DTOs stay epoch ms.
- AppAttestVerifier: an iPhone's App Attest attestation is verified on the
server with the backend PKI -- chain to Apple's root, the nonce bound to
the device key being registered, app id, counter and environment --
when bastion.appattest.app-id is set.
- Skill: Bastion in the demo apps reference; backend reference covers
exception handlers, advice, validation, interceptors, java.time in the
ORM, streaming bodies and HttpProxy, PKI, ECDH, Keccak and secp256k1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Adds native save dialogs, plus open dialogs you can customize, in the new package
com.codename1.io.filechooser.API
Display.showOpenDialog(OpenFileRequest, cb)andDisplay.showSaveDialog(SaveFileRequest, cb). The callback runs on the EDT, including when the user cancels.FileTypeFilter: extensions, MIME types, UTTypes), a suggested name, multi-select or folder picking, and overwrite confirmation.FileDialogOptions (checkbox, choice, text) show up inside the native dialog where the platform allows it, and their values come back inFileDialogResult.FileDialogHintsare platform hints (macOS tag field, Windows client GUID, Android initial URI, ...). A platform ignores the hints it doesn't know.FilePreviewProvidergives a live preview while opening. An accessoryComponentcan be added too.SaveContent(written after the user picks a location and format) or from an existing file.Display.isFileDialogFeatureSupported(...)is a runtime capability query.openFileChooseris unchanged.Ports
FileDialog, or SwingJFileChooserACTION_CREATE_DOCUMENTUIDocumentPickerNSOpenPanelNSSavePanelIFileOpenDialogIFileSaveDialogIFileDialogCustomize, hintsGtkFileChooserGtkFileChooserKnown limitations
allowedFileTypes, which is deprecated on macOS 12 and later, and always confirms before overwriting.Verification
FileDialogRequestTestandFileDialogSupportTest.🤖 Generated with Claude Code